import { InfoCircleFilled } from '@ant-design/icons';
import { useDebounceEffect } from 'ahooks';
import { App, Input, Select, Switch } from 'antd';
import React, { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { DatasetSearchModeEnum, DatasetSearchModeMap } from '@/common/types/dataset/dataset';
import Slider from '@/components/Antd/Slider';
import NormalCollapsible from '@/components/CollapsibleSection/NormalCollapsible';
import { SvgIcon } from '@/components/icon';
import FormLabel from '@/components/MyBox/FormLabel';
import MyRadio from '@/components/MyRadio';
import QuestionTip from '@/components/tooltip/QuestionTip';
import { DatasetParamsProps } from '@/components/workflow/DatasetParamsModal';
import { useSystemStore } from '@/store/useSystemStore';
import { getFilenameFromPath } from '@/utils/common';

const { TextArea } = Input;

// 可复用的功能开关项组件
interface FeatureToggleItemProps {
  title: string;
  description: string;
  isEnabled: boolean;
  onClick: () => void;
  disabled?: boolean;
  disabledMessage?: string;
}

const FeatureToggleItem: React.FC<FeatureToggleItemProps> = ({
  title,
  description,
  isEnabled,
  onClick,
  disabled = false,
  disabledMessage,
}) => {
  const { message } = App.useApp();

  const handleClick = () => {
    if (disabled && disabledMessage) {
      message.warning(disabledMessage);
      return;
    }
    onClick();
  };

  return (
    <div className="mb-2 mt-2 w-full px-2">
      <div
        className={`relative flex cursor-pointer select-none items-center rounded-md border border-gray-300 border-opacity-20 px-4 py-2 ${
          isEnabled ? 'border-primary bg-primary-700' : ''
        }`}
        onClick={handleClick}
      >
        <div className="flex items-center space-x-3">
          <div
            className={`flex h-8 w-8 items-center justify-center rounded-full ${
              isEnabled ? 'bg-green-100' : 'bg-gray-200'
            }`}
          >
            {isEnabled ? (
              <svg
                className="h-5 w-5 text-green-600"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
                />
              </svg>
            ) : (
              <svg
                className="h-5 w-5 text-gray-400"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
                />
              </svg>
            )}
          </div>
          <div>
            <div className="font-medium text-gray-700">{title}</div>
            <div className="text-xs text-gray-600">{description}</div>
          </div>
        </div>
        <div className="ml-auto">
          <Switch checked={isEnabled} />
        </div>
      </div>
    </div>
  );
};

function SearchDatasetParamsConfig({
  searchMode,
  limit,
  similarity,
  usingReRank,
  maxTokens = 3000,
  datasetSearchUsingKnowledgeGraph,
  datasetSearchUsingChunkFilter,
  datasetSearchUsingExtensionQuery,
  datasetSearchExtensionModel,
  datasetSearchExtensionBg,
  onDataChange,
}: {
  searchMode: `${DatasetSearchModeEnum}`;
  limit?: number;
  similarity?: number;
  usingReRank?: boolean;
  maxTokens?: number; // limit max tokens
  datasetSearchUsingKnowledgeGraph?: boolean;
  datasetSearchUsingChunkFilter?: boolean;
  datasetSearchUsingExtensionQuery?: boolean;
  datasetSearchExtensionModel?: string;
  datasetSearchExtensionBg?: string;
  onDataChange: (data: DatasetParamsProps) => void;
}) {
  const { t } = useTranslation();
  const [searchModeExpanded, setSearchModeExpanded] = useState(false);
  const [searchParamExpanded, setSearchParamExpanded] = useState(false);
  const [searchExtensionExpanded, setSearchExtensionExpanded] = useState(false);

  const { reRankModelList, llmModelList } = useSystemStore();
  const [refresh, setRefresh] = useState(false);

  const chatModelSelectList = (() =>
    llmModelList
      .filter((model) => model.usedInQueryExtension && model.isActive)
      .map((item) => ({
        value: item.model,
        label: (
          <div className="flex items-center py-1">
            <SvgIcon
              className="mr-2"
              size="24"
              icon={getFilenameFromPath(item?.avatar || '').replace('.svg', '')}
            />
            <div>{item.name}</div>
            {item?.isConnect ? null : <div className="ml-auto text-xs text-error">失效</div>}
          </div>
        ),
      })))();

  const [data, setData] = useState<DatasetParamsProps>({
    limit,
    similarity,
    searchMode,
    usingReRank: !!usingReRank,
    datasetSearchUsingExtensionQuery,
    datasetSearchExtensionModel: datasetSearchExtensionModel || chatModelSelectList[0]?.value,
    datasetSearchExtensionBg,
    datasetSearchUsingKnowledgeGraph,
    datasetSearchUsingChunkFilter,
  });

  const searchModeList = useMemo(() => {
    const list = Object.values(DatasetSearchModeMap);
    return list;
  }, []);

  const showSimilarity = useMemo(() => {
    if (similarity === undefined) return false;
    if (data.usingReRank) return true;
    if (data.searchMode === DatasetSearchModeEnum.embedding) return true;
    return false;
  }, [data.searchMode, similarity, data.usingReRank]);

  const showReRank = useMemo(() => {
    return usingReRank !== undefined && reRankModelList.length > 0;
  }, [reRankModelList.length, usingReRank]);

  useDebounceEffect(
    () => {
      onDataChange(data);
    },
    [data],
    {
      wait: 100,
    },
  );

  return (
    <div>
      {
        <div className="flex flex-col gap-2">
          {/* Search Mode */}
          <NormalCollapsible
            title="检索模式"
            isExpanded={searchModeExpanded}
            onToggle={() => {
              setSearchModeExpanded(!searchModeExpanded);
            }}
            className="rounded-lg bg-white px-0"
          >
            <div className="flex flex-col items-center">
              <MyRadio
                className="grid-cols-1 p-2"
                list={searchModeList}
                value={data.searchMode}
                onChange={(e) => {
                  setData({
                    ...data,
                    searchMode: e as `${DatasetSearchModeEnum}`,
                  });
                  setRefresh(!refresh);
                }}
              />
              {data.searchMode === DatasetSearchModeEnum.mixedRecall && (
                <div className="flex w-full items-center px-6 py-2">
                  <div className="ml-7 flex items-center">
                    <div className="text-nowrap text-text-4">开启知识图谱检索</div>
                    <QuestionTip
                      className="ml-1"
                      title={t('core.dataset.search.mode.knowledgeGraph desc')}
                    />
                  </div>
                  <div className="ml-auto">
                    <Switch
                      checked={data.datasetSearchUsingKnowledgeGraph}
                      onChange={(e) => {
                        setData({ ...data, datasetSearchUsingKnowledgeGraph: e });
                      }}
                    />
                  </div>
                </div>
              )}

              <div className="h-[1px] w-[95%] bg-line-1" />

              <FeatureToggleItem
                title={t('core.dataset.search.ReRank')}
                description={t('core.dataset.search.ReRank desc')}
                isEnabled={!!data.usingReRank}
                onClick={() => {
                  setData({
                    ...data,
                    usingReRank: !data.usingReRank,
                  });
                  setRefresh((state) => !state);
                }}
                disabled={!showReRank}
                disabledMessage={t('core.ai.Not deploy rerank model')}
              />

              <FeatureToggleItem
                title={t('core.dataset.search.Chunk Filter')}
                description={t('core.dataset.search.Chunk Filter desc')}
                isEnabled={!!data.datasetSearchUsingChunkFilter}
                onClick={() => {
                  setData({
                    ...data,
                    datasetSearchUsingChunkFilter: !data.datasetSearchUsingChunkFilter,
                  });
                  setRefresh((state) => !state);
                }}
              />
            </div>
          </NormalCollapsible>
          <NormalCollapsible
            title="检索过滤"
            isExpanded={searchParamExpanded}
            className="rounded-lg bg-white px-0"
            onToggle={() => {
              setSearchParamExpanded(!searchParamExpanded);
            }}
          >
            <div className="flex flex-col p-2">
              {limit !== undefined && (
                <div>
                  <div className="flex items-center justify-between">
                    <div className="ml-2 flex items-center space-x-2">
                      <span className="font-medium text-gray-700">
                        {t('core.dataset.search.Max Tokens')}
                      </span>
                      <QuestionTip
                        className="ml-1"
                        title={t('core.dataset.search.Max Tokens Tips')}
                      />
                    </div>
                  </div>
                  <div className="flex items-center px-2">
                    <div className="mr-4 flex-1 pt-4">
                      <Slider
                        size="small"
                        min={100}
                        max={maxTokens}
                        step={50}
                        value={data.limit ?? 1000}
                        onChange={(val) => {
                          setData({
                            ...data,
                            limit: val,
                          });
                          setRefresh(!refresh);
                        }}
                        tooltip={undefined}
                      />
                      <div className="flex justify-between text-xs text-text-3">
                        <span>100</span>
                        <span>{maxTokens}</span>
                      </div>
                    </div>
                    <div className="w-16 rounded-md border border-line-2 px-3 py-1 text-sm font-font-weight-400 text-text-5">
                      {data.limit}
                    </div>
                  </div>
                </div>
              )}
              <div className="mt-2">
                <div className="flex items-center justify-between">
                  <div className="ml-2 flex items-center space-x-2">
                    <span className="font-medium text-gray-700">
                      {t('core.dataset.search.Min Similarity')}
                    </span>
                    <QuestionTip
                      className="ml-1"
                      title={t('core.dataset.search.Min Similarity Tips')}
                    />
                  </div>
                </div>
                <div className="flex-1">
                  {showSimilarity ? (
                    <div className="flex items-center px-2">
                      <div className="mr-4 flex-1 pt-4">
                        <Slider
                          size="small"
                          min={0}
                          max={1}
                          step={0.01}
                          value={data.similarity ?? 0.5}
                          onChange={(val) => {
                            setData({
                              ...data,
                              similarity: val,
                            });
                            setRefresh(!refresh);
                          }}
                        />
                        <div className="flex justify-between text-xs text-text-3">
                          <span>0.0</span>
                          <span>1.0</span>
                        </div>
                      </div>
                      <div className="w-16 rounded-md border border-line-2 px-3 py-1 text-sm font-font-weight-400 text-text-5">
                        {data.similarity ?? 0.5}
                      </div>
                    </div>
                  ) : (
                    <div className="ml-2 text-gray-600">
                      {t('core.dataset.search.No support similarity')}
                    </div>
                  )}
                </div>
              </div>
            </div>
          </NormalCollapsible>
          <NormalCollapsible
            title="问题补全"
            isExpanded={searchExtensionExpanded}
            className="rounded-lg bg-white px-0"
            onToggle={() => {
              setSearchExtensionExpanded(!searchExtensionExpanded);
            }}
            extra={
              <div onClick={(e) => e.stopPropagation()}>
                <Switch
                  value={data.datasetSearchUsingExtensionQuery}
                  onChange={(e) => {
                    setData({
                      ...data,
                      datasetSearchUsingExtensionQuery: e,
                    });
                  }}
                />
              </div>
            }
          >
            <div className="flex flex-col p-2">
              <div className="flex flex-1 items-center gap-2 rounded-lg border border-@brand-color-disabled bg-@brand-color-light p-2">
                <InfoCircleFilled
                  className="ml-2 mt-1 self-start"
                  size={28}
                  style={{ color: 'var(--brand-color)' }}
                />
                <div className="max-w-[400px] text-xs">
                  {t('core.dataset.Query extension intro')}
                </div>
              </div>
              {data.datasetSearchUsingExtensionQuery === true && (
                <>
                  <div className="mt-4 flex flex-col gap-2">
                    <FormLabel>{t('core.ai.Model.select')}</FormLabel>
                    <Select
                      className="w-full"
                      value={data.datasetSearchExtensionModel}
                      options={chatModelSelectList}
                      onChange={(e) => {
                        setData({
                          ...data,
                          datasetSearchExtensionModel: e,
                        });
                      }}
                    />
                  </div>
                  <div className="mt-3">
                    <div className="flex items-center">
                      <FormLabel>{t('core.app.edit.Query extension background prompt')}</FormLabel>
                      <QuestionTip
                        className="ml-1"
                        title={t('core.app.edit.Query extension background tip')}
                      />
                    </div>
                    <div className="mt-2">
                      <TextArea
                        className="h-auto"
                        rows={4}
                        value={data.datasetSearchExtensionBg}
                        onChange={(e) => {
                          setData({
                            ...data,
                            datasetSearchExtensionBg: e.target.value,
                          });
                        }}
                        placeholder={t('core.module.QueryExtension.placeholder')}
                      />
                    </div>
                  </div>
                </>
              )}
            </div>
          </NormalCollapsible>
        </div>
      }
    </div>
  );
}

export default React.memo(SearchDatasetParamsConfig);
